# -*- coding: utf-8 -*-
import uuid
from typing import List, Optional

from sqlalchemy import func, or_

from db.session import with_session
from db.models.files import EmergencyFile
from utils.file_utils import to_rel_path


@with_session
def db_get_ep_files(session, *, name_like: str = None, offset: int = 0, limit: int = 50):
    query = session.query(EmergencyFile) \
        .filter(EmergencyFile.is_delete.is_(False))
    if name_like:
        query = query.filter(EmergencyFile.name.ilike(f"%{name_like}%"))
    total = query.count()
    items = query.order_by(EmergencyFile.create_time.desc()).offset(offset).limit(limit).all()
    return items, total


@with_session
def db_get_ep_files_by_user_groups(session, user_group_ids: List[int], *, name_like: str = None, offset: int = 0, limit: int = 50):
    """根据用户组ID列表获取应急预案文件"""
    if not user_group_ids:
        return [], 0
    
    query = session.query(EmergencyFile) \
        .filter(EmergencyFile.is_delete.is_(False)) \
        .filter(
            or_(
                EmergencyFile.group_ids == [],
                func.json_contains(EmergencyFile.group_ids, str(user_group_ids))
            )
        )
    if name_like:
        query = query.filter(EmergencyFile.name.ilike(f"%{name_like}%"))
    total = query.count()
    items = query.order_by(EmergencyFile.create_time.desc()).offset(offset).limit(limit).all()
    return items, total


@with_session
def db_get_ep_file_by_id(session, file_id: uuid.UUID) -> Optional[EmergencyFile]:
    if isinstance(file_id, str):
        file_id = uuid.UUID(file_id)
    return session.query(EmergencyFile) \
        .filter(EmergencyFile.id == file_id) \
        .first()


@with_session
def db_get_ep_file_by_name(session, file_hash_name: str) -> Optional[EmergencyFile]:
    return session.query(EmergencyFile) \
        .filter(EmergencyFile.hash_name == file_hash_name, EmergencyFile.is_delete.is_(False)) \
        .first()


@with_session
def db_get_ep_files_by_origin_name(session, name_like: str) -> List[EmergencyFile]:
    if not name_like:
        return session.query(EmergencyFile).filter(EmergencyFile.is_delete.is_(False)).all()
    return session.query(EmergencyFile) \
        .filter(EmergencyFile.is_delete.is_(False)) \
        .filter(EmergencyFile.name.ilike(f"%{name_like}%")) \
        .all()


@with_session
def db_add_ep_file(session, user_id: int, hash_name: str, file_name: str, location: str, file_type: str,
                   size: float, scene_type: Optional[list] = None, group_ids: Optional[list] = None,
                   accident_type: Optional[int] = None):
    f = session.query(EmergencyFile).filter(EmergencyFile.hash_name == hash_name).first()
    if f:
        f.is_delete = False
        f.created_by = user_id
        f.name = file_name
        f.hash_name = hash_name
        f.location = to_rel_path(location)
        f.file_type = file_type
        f.file_size = size
        if scene_type is not None:
            f.scene_type = scene_type
        if group_ids is not None:
            f.group_ids = group_ids
        if accident_type is not None:
            f.accident_type = accident_type
        session.commit()
        return f, True
    new_file = EmergencyFile(
        created_by=user_id,
        name=file_name,
        hash_name=hash_name,
        location=to_rel_path(location),
        file_type=file_type,
        file_size=size,
        scene_type=scene_type or [],
        group_ids=group_ids or [],
        accident_type=accident_type,
    )
    session.add(new_file)
    session.commit()
    return new_file, False


@with_session
def db_update_ep_file_delete_state(session, file_id: uuid.UUID, delete: bool):
    file = session.query(EmergencyFile).get(file_id)
    if not file:
        return None
    file.is_delete = delete
    session.commit()
    return True


@with_session
def db_update_ep_file_info(session, file_id: uuid.UUID, name: str | None = None,
                           scene_type: list | None = None,
                           group_ids: list[int] | None = None,
                           accident_type: int | None = None) -> Optional[EmergencyFile]:
    file = session.query(EmergencyFile).get(file_id)
    if not file:
        return None
    if name is not None:
        file.name = name
    if scene_type is not None:
        file.scene_type = scene_type
    if group_ids is not None:
        file.group_ids = group_ids
    if accident_type is not None:
        file.accident_type = accident_type
    session.commit()
    return file

